package edu.ntu.im.p2ptrade.entity;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public class ItemRepository implements Serializable{
	private Integer max = 0;

	private List<Item> items = new LinkedList<Item>();
	private Date lastQueried = null;
	private Date lastModified = new Date();
	
	static final long serialVersionUID = 649912149791811557L;
	private Map<Integer, Item> itemmap = new HashMap<Integer, Item>();

	private static ItemRepository repo;
	
	final static private String itemRepo= "ItemRepo.obj";
	
	public static void initialize(){
		File f = new File(itemRepo);
		if (!f.exists()){
			try {
				f.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
			return; 
		}
		FileInputStream fis;
		try {
			fis = new FileInputStream(f);
			ObjectInputStream ois = new ObjectInputStream(fis);
			repo = (ItemRepository) ois.readObject();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	
	}

	public static ItemRepository getInstance() {
		if (repo == null) {
			repo = new ItemRepository();
		}
		return repo;
	}
	
	public void removeById(Integer id){
		this.items.remove(this.itemmap.get(id));
		this.itemmap.remove(id);
	}
	
	

	private ItemRepository() {
		/*Item item1 = new Item();
		item1.setName("japan travel");
		item1.setMemo("extremly fun");
		item1.setPhotoUrl("http://www.sosauce.com/photo/loadImage2.do?s=25783-2-qIRWWwSlztlZ.jpg");
		this.items.add(item1);*/
	}

	public List<Item> getItems() {
		return items;
	}

	public synchronized void addItem(Item item) {
		item.setId(max++);
		this.items.add(item);
		this.itemmap.put(item.getId(), item);
		this.lastModified = new Date();
		
		this.save(this);
	}
	
	private void save(ItemRepository repo){
		File f = new File(itemRepo);
		try {
			FileOutputStream fos = new FileOutputStream(f);
			ObjectOutputStream oos = new ObjectOutputStream(fos);
			oos.writeObject(repo);
			oos.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	public synchronized void updateItem(Item item) {
		Item original = this.itemmap.get(item.getId());
		original.setName(item.getName());
		original.setMemo(item.getMemo());
		this.lastModified = new Date();
		this.save(this);
	}

	
	public Date getLastModified() {
		return lastModified;
	}

	public Date getLastQueried() {
		return lastQueried;
	}

	public synchronized void deleteItem(Item item) {
		if (this.itemmap.get(item.getId())!=null){
		this.items.remove(itemmap.remove(item.getId()));
		}
		this.lastModified = new Date();
		this.save(this);
	}

	public List<Item> fetchItems() {
		this.lastQueried = new Date();
		return items;
	}

	public Item getItem(int i) {
		Item item = null;
		for (Item cur:items){
			if (cur.getId() == i){
				item = cur;
				break;
			}
		}
		return item;
	}

	public boolean hasThis(Integer id) {
		return this.itemmap.containsKey(id);
	}
	
	

}
